package com.spring.demo.publicutil.thread;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 可以将取消等待的线程
 * 可以在未获得锁时被打断的线程锁：lockInterruptibly
 * 打断线程的方法 interrupt
 *
 * @author youjc
 * lock.lock方法线程被中断时，是该线程已经获取了锁，
 * 在检查中断标志，发现自己被人中断了，则抛出异常，
 * 因此在finally中一定要释放锁。
 *
 * lock.lockInterruptibly()：如果没有获取锁，并中断了，
 * 则立马抛出异常，如果你catch，则在后面的处理中，
 * 你需要区分是获取了锁还是没有获取锁！！！不要轻易lock.unlock(),
 * 也不要不unlock，则会造成严重后果。
 */
public class T02_ReentrantLock2 {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();

        Thread t1 = new Thread(()->{
            lock.lock();// 获取锁
            try {
                System.out.println("t1 线程获取到了锁");
                TimeUnit.SECONDS.sleep(3);
                System.out.println("t1 end");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("线程 t1 被打断了");
            }finally {
                lock.unlock();// 释放锁
            }
        });
        t1.start();

        Thread t2 = new Thread(()->{
            try {
                System.out.println("t2 线程开始");
                lock.lockInterruptibly();// 可以对 interrupt 做出相应
                System.out.println("t2 线程 获取到了锁");
                TimeUnit.SECONDS.sleep(5);
                System.out.println("t2 end");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("线程 t2 被打断了");
            }finally {
                // 线程是否获取到了锁  ， 获取到锁了 在释放锁
                if(lock.tryLock()){
                    System.out.println("线程二 获取到了锁 进行释放锁");
                    lock.unlock();
                }else {
                    System.out.println("线程 t2 没有获取到锁");
                }

            }
        });
        t2.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //t2.interrupt();// 打断线程二的等待
    }
}
